//
//  TCPSocketIOPackTransport.m
//  RunSketch
//
//  Created by Brian on 9/5/09.
//  Copyright 2009 Tellart. All rights reserved.
//

#import "TCPSocketIOPackTransport.h"
#import "SketchProtocol.h"


@implementation TCPSocketIOPackTransport

@synthesize deviceAddress, ioPack;

-(id)init
{
    if (self = [super init])
    {
        hasBeenSetUp = NO;
        
        self.ioPack = [[IOPack alloc] initWithTransport:self];
    }
    return self;
}

//set up the NADAMobileIOHelper
- (void)connectToHostName:(NSString*)pHostName port:(unsigned short)pPort
{
    if (pHostName == nil) return;

    NSLog(@"[TCPSocketIOPackTransport initWith...]");
    
    deviceAddress = nil;
    
    if (csocket) [csocket close];
    
    csocket = [Socket socket];
    [csocket retain];
    
    hostName = pHostName;
    [hostName retain];
    port = pPort;
    
    @try {
        isConnecting = YES;
        [csocket setBlocking:NO];
        //[csocket setBlocking:YES];
        [csocket connectToHostName:hostName port:port];
        isConnecting = NO;
    }
    @catch (id theException) {
        NSLog(@"TCPSocketIOPackTransport: Exception while trying to connect socket to %@:%d : %@", hostName, port, theException);
        if ([[NSString stringWithFormat:@"%@", theException] isEqualToString: @"Socket: Connect failed: Operation now in progress"]) {
            isConnecting = YES;
        } else {
            //some other error connecting to the sketch server
            isConnecting = NO;
            //sketchServerNameResolved = NULL;
        }
    }
    if (isConnecting || [csocket isConnected]) {
        deviceAddress = [NSString stringWithFormat:@"%@://%@:%d", kDeviceAddressSchemeRemote, pHostName, pPort];
        [deviceAddress retain];
        NSLog(@"[TCPSocketIOPackTransport connectToHostName]: set deviceAddress to %@", deviceAddress);

        hasBeenSetUp = YES;
    }
}


- (void)dealloc
{
    @try {
        [csocket close];
    }
    @catch (id theException) {
        NSLog(@"TCPSocketIOPackTransport: Exception while trying to close socket: %@", theException);
    }
    [hostName release];
    [deviceAddress release];
    [csocket release];
    [super dealloc];
}

/** Begin IOPackTransport implementation **/

- (int)numOutputChannels
{
    return kSketchProtocol_numSetValues;
}

- (int)numInputChannels
{
    return kSketchProtocol_numSetValues;
}

- (BOOL)isConnectedAndReady
{
    return hasBeenSetUp && [csocket isConnected] && !isConnecting;
}

- (BOOL)isReadable
{
    return hasBeenSetUp && [csocket isConnected] && [csocket isReadable];
}

- (BOOL)isWritable
{
    return hasBeenSetUp && [csocket isConnected] && [csocket isWritable];
}

/*
- (int)readData:(NSMutableData*)data
{
    return [csocket readData:data];
}

- (int)readDataAndReplace:(NSMutableData*)data
{
    return [csocket readDataAndReplace:data];
}
*/

- (int)read
{
    if (!hasBeenSetUp) [NSException raise:TCPSocketIOPackTransport_EX_NOT_SET_UP 
                        format:TCPSocketIOPackTransport_EX_NOT_SET_UP];
    return [csocket read];
}

- (char*)readBuffer
{
    if (!hasBeenSetUp) [NSException raise:TCPSocketIOPackTransport_EX_NOT_SET_UP 
                        format:TCPSocketIOPackTransport_EX_NOT_SET_UP];
    return csocket.readBuffer;
}

- (BOOL)writeData:(NSData*)data
{
    if (!hasBeenSetUp) [NSException raise:TCPSocketIOPackTransport_EX_NOT_SET_UP 
                        format:TCPSocketIOPackTransport_EX_NOT_SET_UP];
    //NSLog(@"TCPSocketIOPackTransport: writeData");
    return [csocket writeData:data];
}

/** End IOPackTransport implementation **/



@end
